package my.opencv;

import dto.ImageDto;
import find.TestIDCard;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import xiugai.other.OpencvUtil;

public class CascadeClassifierUtils {
    public static CascadeClassifier loadCascadeClassifier(CascadeClassifier faceDetector,String path) {
        if(null == faceDetector) {
            return new CascadeClassifier(path);
        }else {
            faceDetector.load(path);
        }
        return faceDetector;
    }

    /**
     * 循环进行人脸识别
     * */
    public static Mat faceLoop(Mat src){
        Rect[] rects= null;
        //默认人脸识别失败时图像旋转90度
        int k=30;
        for(int i=0;i<360/k;i++){
            //人脸识别
            rects= findFaces (src);
            if(rects==null){
                src = rotate(src,k);
            }else{
                break;
            }
        }
        if(null!=rects && rects.length>0) {
           return OpencvImageUtils.cutRect(OpencvImageUtils.getMixRect(rects), src);
        }else {
            return null;
        }
    }

    /**
     * 循环进行人脸识别
     * */
    public static ImageDto correctIDCardUp(Mat org) {
        Mat src=org.clone();
        Mat gray=new Mat();
        Imgproc.cvtColor(src,gray, Imgproc.COLOR_BGR2GRAY);
        Rect[] rects = null;
        //默认人脸识别失败时图像旋转90度
        int k=0;
        for(int i=0;i<11;i++){
            //人脸识别
            rects= findFaces (src);
            if(rects==null || rects.length==0){
                k = 30+i*30;
                src = rotate(org,k);

                Imgcodecs.imwrite("C:/Users/admin/Desktop/cut/fanzhuan.jpg", src);
            }else{
                break;
            }
        }
        if(null!=rects && rects.length>0) {
            src = rotate (org,k);
            Mat face= OpencvImageUtils.cutRect(OpencvImageUtils.getMixRect(rects), src);

            Imgcodecs.imwrite("C:/Users/admin/Desktop/cut/test_faceLoop00.jpg", face);
            int angle = OpencvImageUtils.getRotationAngleByEyes(face);
            Mat standardMat = null;
            if(angle >=3) {
                standardMat = OpencvImageUtils.rotate3(src, angle);
            }else {
                standardMat = src.clone();
            }



            Imgcodecs.imwrite("C:/Users/admin/Desktop/cut/56555555555.jpg", standardMat);
            Rect[]faceRects = CascadeClassifierUtils.findFaces(standardMat);
            Rect faceRect =OpencvImageUtils.getMixRect(faceRects);;
            TestIDCard.threadLocal.get().put("touxiang",new Rect(faceRect.x-face.width()/2,faceRect.y-face.height()/2,face.width()*2,face.height()*2));
            Rect[] eyesRects = CascadeClassifierUtils.findEyes(new Mat(standardMat,faceRect));
            if(null != eyesRects && eyesRects.length>0) {
                TestIDCard.threadLocal.get().put("eyesRects", eyesRects[0]);
            }
            Imgcodecs.imwrite("C:/Users/admin/Desktop/cut/standardMatFace.jpg", new Mat(standardMat,faceRect));
            return new ImageDto(standardMat,faceRect);

        }else {
            return null;
        }
    }


    /**
     * 图片旋转
     * @param splitImage
     * @param angle
     * @return
     */
    public static Mat rotate(Mat splitImage, double angle){
        double thera = angle * Math.PI / 180;
        double a = Math.sin(thera);
        double b = Math.cos(thera);

        int wsrc = splitImage.width();
        int hsrc = splitImage.height();

        int wdst = (int) (hsrc * Math.abs(a) + wsrc * Math.abs(b));
        int hdst = (int) (wsrc * Math.abs(a) + hsrc * Math.abs(b));
        Mat imgDst = new Mat(hdst, wdst, splitImage.type());

        Point pt = new Point(splitImage.cols() / 2, splitImage.rows() / 2);
        // 获取仿射变换矩阵
        Mat affineTrans = Imgproc.getRotationMatrix2D(pt, angle, 1.0);

        //System.out.println(affineTrans.dump());
        // 改变变换矩阵第三列的值
        affineTrans.put(0, 2, affineTrans.get(0, 2)[0] + (wdst - wsrc) / 2);
        affineTrans.put(1, 2, affineTrans.get(1, 2)[0] + (hdst - hsrc) / 2);

        Imgproc.warpAffine(splitImage, imgDst, affineTrans, imgDst.size(),
                Imgproc.INTER_CUBIC | Imgproc.WARP_FILL_OUTLIERS);
        return imgDst;
    }

    public static Rect[] findFaces(Mat mat) {
        CascadeClassifier classifier = loadCascadeClassifier(null,"D:/XF/opencv/opencv4_4/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");
        classifier.load("D:\\XF\\opencv\\opencv4_4\\build\\etc\\haarcascades\\haarcascade_frontalface_default.xml");
        classifier.load("D:\\XF\\opencv\\opencv4_4\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml");
        classifier.load("D:\\XF\\opencv\\opencv4_4\\build\\etc\\haarcascades\\haarcascade_frontalface_alt_tree.xml");
        // 在图片中检测人脸
        MatOfRect faceDetections = new MatOfRect();
        classifier.detectMultiScale(mat, faceDetections, 1.1f, 1, 0/*, new Size(50, 50), new Size(800, 800)*/);
        Rect[] rects = faceDetections.toArray();
        return rects;

    }

    public static Rect[] findEyes(Mat mat) {
        CascadeClassifier classifier = loadCascadeClassifier(null,"D:\\XF\\opencv\\opencv4_4\\sources\\data\\haarcascades\\haarcascade_eye.xml");
        MatOfRect faceDetections = new MatOfRect();
        classifier.detectMultiScale(mat, faceDetections, 1.1f, 3, 0/*, minSize, maxSize*/);
        Rect[] rects = faceDetections.toArray();
        return rects;

    }
    public static Rect[] findEyeLasses(Mat mat) {
        CascadeClassifier classifier = loadCascadeClassifier(null,"D:\\XF\\opencv\\opencv4_4\\sources\\data\\haarcascades_cuda\\haarcascade_eye_tree_eyeglasses.xml");
        MatOfRect faceDetections = new MatOfRect();
        classifier.detectMultiScale(mat, faceDetections, 1.1f, 3, 0/*, minSize, maxSize*/);
        Rect[] rects = faceDetections.toArray();
        Imgcodecs.imwrite("C:/Users/admin/Desktop/cut/eyeglasses.jpg", new Mat(mat,rects[0]));
        return rects;

    }
}
